home *** CD-ROM | disk | FTP | other *** search
Wrap
Java Source | 1997-06-19 | 26.3 KB | 968 lines
package symantec.itools.awt; import java.awt.Panel; import java.awt.Component; import java.awt.Scrollbar; import java.awt.Dimension; import java.awt.Color; import java.awt.Rectangle; import java.awt.Graphics; import java.awt.Event; import java.awt.LayoutManager; import symantec.itools.awt.shape.Rect; import symantec.itools.awt.KeyPressManagerPanel; /** * Creates a container with scroll bars. * <p> * The ScrollingPanel can contain one panel that can contain visual components * and other panels. The ScrollingPanel will be displayed with attached scroll bars. * <p> * Use this component to display a region that allows the user to scroll * through all items in the panel, and specifically to: * <UL> * <DT>╖ create a subcontainer that organizes container space within an Applet, Frame or Dialog container. This simplifies your component layout task.</DT> * <DT>╖ hold other specialized Panel containers.</DT> * </UL> * @version 1.0, Nov 26, 1996 * @author Symantec */ // 05/08/97 CAR Changed handleEvent to check that event target is either the HBar OR the VBar // before executing a scroll. This fixed the bug where a scroll event that was // not targeted at the VBar would cause the VBar logic to execute. // 02/15/97 RKM Changed add to call setComponent // Changed setComponent to add the component before the VBar, HBar, & cornerRect // Removed bOsFlag and added isSolaris to OS // Added handling of correct scrollbar width for the Mac public class ScrollingPanel extends KeyPressManagerPanel { private Component spComponent; private int width; private int height; private int xCoord, yCoord; private Scrollbar VBar = null; private Scrollbar HBar= null; private boolean bVBarVisible; private boolean bHBarVisible; private boolean bCornerRectVisible; private int vPageSize; private int hPageSize; private Dimension dimComponent; private int vGapWid; private int hGapHt; private boolean bAllowShowVBar = true; private boolean bAllowShowHBar = true; private int scrollLineIncrement = 1; private Rect cornerRect; //-------------------------------------------------- // constructors //-------------------------------------------------- /** * Constructs a default ScrollingPanel. * The panel is initialized with a null component, zero * minimum height and zero minimum width. */ public ScrollingPanel() { this(null, 0, 0); } /** * Constructs a new ScrollingPanel initialized with the * specified component, minimum height and minimum width. * @param component the component (usually a Panel) to be * scrolled * @param minWidth the value to be used for the minimumSize() * width of the ScrollingPanel * @param minHeight the value to be used for the minimumSize() * height of the ScrollingPanel */ public ScrollingPanel(Component component, int minWidth, int minHeight) { this.spComponent = component; this.width = minWidth; this.height = minHeight; xCoord = 0; yCoord = 0; bVBarVisible = false; bHBarVisible = false; bCornerRectVisible = false; vPageSize = 0; hPageSize = 0; vGapWid = 6; hGapHt = 6; dimComponent = new Dimension(0,0); VBar = new Scrollbar(); VBar.setBackground(Color.lightGray); HBar = new Scrollbar(Scrollbar.HORIZONTAL); HBar.setBackground(Color.lightGray); cornerRect = new Rect(); cornerRect.setForeground(Color.lightGray); cornerRect.setFillColor(Color.lightGray); cornerRect.setFillMode(true); setLayout(null); addInternalComponents(); VBar.hide(); HBar.hide(); cornerRect.hide(); if (spComponent != null) { super.add(spComponent, -1); placeComponents(); } } /** * Sets the value to be used for the minimumSize() width * of the ScrollingPanel. * @param minWidth the value to be used for the minimumSize() * width of the ScrollingPanel * @see #getMinimumWidth */ public void setMinimumWidth(int minWidth) { this.width = minWidth; } /** * Gets the current value used for the minimumSize() * width of the ScrollingPanel. * @return the current width value */ public int getMinimumWidth() { return this.width; } /** * Sets the value to be used for the minimumSize() * height of the ScrollingPanel. * @param minHeight the value to be used for the minimumSize() * height of the ScrollingPanel * @see #getMinimumHeight */ public void setMinimumHeight(int minHeight) { this.height = minHeight; } /** * Gets the value used for the minimumSize() height * of the ScrollingPanel. * @return current height value * @see #setMinimumHeight */ public int getMinimumHeight() { return this.height; } /** * Sets the vertical gap amount between the container * in ScrollingPanel and the vertical scroll bar. * @param gapPixels the size of vertical gap in pixels * @see #getVerticalGap */ public void setVerticalGap(int gapPixels) { vGapWid = gapPixels; invalidate(); } /** * Gets the current vertical gap amount between the * container in ScrollingPanel and the vertical scroll * bar. * @return the size of vertical gap in pixels * @see #setVerticalGap */ public int getVerticalGap() { return vGapWid; } /** * Sets the horizontal gap amount between the container * in ScrollingPanel and the horizontal scroll bar. * @param gapPixels the size of horizontal gap in pixels * @see #getHorizontalGap */ public void setHorizontalGap(int gapPixels) { hGapHt = gapPixels; invalidate(); } /** * Gets the current horizontal gap amount between the * container in ScrollingPanel and horizontal scroll * bar. * @return the size of horizontal gap in pixels * @see #setHorizontalGap */ public int getHorizontalGap() { return hGapHt; } /** * Sets whether or not the vertical scrollbar should be * made visible when necessary or should never be made * visible. * @param cond if true, show the scrollbar when necessary; * if false, never show the scrollbar * @see #getShowVerticalScroll */ public void setShowVerticalScroll(boolean cond) { if (bAllowShowVBar != cond) { bAllowShowVBar = cond; invalidate(); } } /** * Gets the current vertical scrollbar visibility flag. * @return the visibility flag. If true, show the scrollbar when * necessary; if false, never show the scrollbar * @see #setShowVerticalScroll */ public boolean getShowVerticalScroll() { return bAllowShowVBar; } /** * Sets whether or not the horizontal scrollbar should be * made visible when necessary or should never be made * visible. * @param cond if true, show the scrollbar when necessary; * if false, never show the scrollbar * @see #getShowHorizontalScroll */ public void setShowHorizontalScroll(boolean cond) { if (bAllowShowHBar != cond) { bAllowShowHBar = cond; invalidate(); } } /** * Gets the current horizontal scrollbar visibility flag. * @return the visibility flag. If true, show the scrollbar when * necessary; if false, never show the scrollbar * @see #setShowHorizontalScroll */ public boolean getShowHorizontalScroll() { return bAllowShowHBar; } /** * Sets the pixel increment to scroll for every scrollbar * arrow press. * @param scrollLineIncrement the pixel value to scroll, * default is one pixel * @see #getScrollLineIncrement */ public void setScrollLineIncrement(int scrollLineIncrement) { this.scrollLineIncrement = scrollLineIncrement; } /** * Gets the current pixel scroll increment. * @return the current scroll increment in pixels * @see #setScrollLineIncrement */ public int getScrollLineIncrement() { return scrollLineIncrement; } /** * Sets the component in the ScrollingPanel. * @param comp the new component to be in the ScrollingPanel * @see #getComponent */ public void setComponent(Component comp) { super.removeAll(); //If we had a component, remove it if (this.spComponent != null) super.remove(this.spComponent); //Keep track of the new component this.spComponent = comp; //Add the new component at the end super.add(spComponent, -1); addInternalComponents(); invalidate(); } /** * Gets the current component in the ScrollingPanel. * @return the current component in the ScrollingPanel * @see #setComponent */ public Component getComponent() { return this.spComponent; } /** * Processes events for this component. * This is a standard Java AWT method which gets called by the AWT * to handle this component's events. The default handler for * components dispatches to one of the following methods as needed: * action(), gotFocus(), lostFocus(), keyDown(), keyUp(), mouseEnter(), * mouseExit(), mouseMove(), mouseDrag(), mouseDown(), or mouseUp(). * * @param evt the event to handle * @return true if the event was handled and no further action is needed, * false to pass the event to this component's parent * @see java.awt.Component#action * @see java.awt.Component#gotFocus * @see java.awt.Component#lostFocus * @see java.awt.Component#keyDown * @see java.awt.Component#keyUp * @see java.awt.Component#mouseEnter * @see java.awt.Component#mouseExit * @see java.awt.Component#mouseMove * @see java.awt.Component#mouseDrag * @see java.awt.Component#mouseDown * @see java.awt.Component#mouseUp */ public boolean handleEvent(Event evt) { if (evt.target == HBar || evt.target == VBar) { switch (evt.id) { case Event.SCROLL_LINE_UP: { if (evt.target == HBar) { scrollLeft(); } else { scrollUp(); } return true; } case Event.SCROLL_LINE_DOWN: { if (evt.target == HBar) { scrollRight(); } else { scrollDown(); } return true; } case Event.SCROLL_PAGE_UP: { if (evt.target == HBar) { scrollPageLeft(); } else { scrollPageUp(); } return true; } case Event.SCROLL_PAGE_DOWN: { if (evt.target == HBar) { scrollPageRight(); } else { scrollPageDown(); } return true; } case Event.SCROLL_ABSOLUTE: { if (evt.target == HBar) { scrollHorizontalAbsolute(((Integer)evt.arg).intValue()); } else { scrollVerticalAbsolute(((Integer)evt.arg).intValue()); } return true; } } } return super.handleEvent(evt); } /** * Handles redrawing of this component on the screen. * This is a standard Java AWT method which gets called by the Java * AWT (repaint()) to handle repainting this component on the screen. * The graphics context clipping region is set to the bounding rectangle * of this component and its <0,0> coordinate is this component's * top-left corner. * Typically this method paints the background color to clear the * component's drawing space, sets graphics context to be the foreground * color, and then calls paint() to draw the component. * * It is overridden here to avoid unneeded clearing of the background. * * @param g the graphics context * @see java.awt.Component#repaint * @see #paint */ public void update(Graphics g) { paint(g); } /** * Paints this component using the given graphics context. * This is a standard Java AWT method which typically gets called * by the AWT to handle painting this component. It paints this component * using the given graphics context. The graphics context clipping region * is set to the bounding rectangle of this component and its <0,0> * coordinate is this component's top-left corner. * * @param g the graphics context used for painting * @see java.awt.Component#repaint * @see #update */ public void paint(Graphics g) { if (spComponent == null) { return; } placeComponents(); } /** * Scrolls one pixel up. * @see #scrollDown * @see #scrollLeft * @see #scrollRight */ public void scrollUp() { yCoord += scrollLineIncrement; if (yCoord > 0) { yCoord = 0; } VBar.setValue(-yCoord); repaint(); } /** * Scrolls one pixel left. * @see #scrollRight * @see #scrollUp * @see #scrollDown */ public void scrollLeft() { xCoord += scrollLineIncrement; if (xCoord > 0) { xCoord = 0; } HBar.setValue(-xCoord); repaint(); } /** * Scrolls one pixel down. * @see #scrollUp * @see #scrollLeft * @see #scrollRight */ public void scrollDown() { yCoord -= scrollLineIncrement; if ( (-yCoord) > VBar.getMaximum()) { yCoord = -VBar.getMaximum(); } VBar.setValue(-yCoord); repaint(); } /** * Scrolls one pixel right. * @see #scrollLeft * @see #scrollUp * @see #scrollDown */ public void scrollRight() { xCoord -= scrollLineIncrement; if ( (-xCoord) > HBar.getMaximum()) { xCoord = -HBar.getMaximum(); } HBar.setValue(-xCoord); repaint(); } /** * Scrolls one "page" up. * @see #scrollPageDown * @see #scrollPageLeft * @see #scrollPageRight */ public void scrollPageUp() { yCoord += vPageSize; if (yCoord > 0) { yCoord = 0; } VBar.setValue(-yCoord); repaint(); } /** * Scrolls one "page" left. * @see #scrollPageRight * @see #scrollPageUp * @see #scrollPageDown */ public void scrollPageLeft() { xCoord += hPageSize; if (xCoord > 0) { xCoord = 0; } HBar.setValue(-xCoord); repaint(); } /** * Scrolls one "page" down. * @see #scrollPageUp * @see #scrollPageLeft * @see #scrollPageRight */ public void scrollPageDown() { yCoord -= vPageSize; if ( (-yCoord) > VBar.getMaximum()) { yCoord = -VBar.getMaximum(); } VBar.setValue(-yCoord); repaint(); } /** * Scrolls one "page" right. * @see #scrollPageLeft * @see #scrollPageUp * @see #scrollPageDown */ public void scrollPageRight() { xCoord -= hPageSize; if ( (-xCoord) > HBar.getMaximum()) { xCoord = -HBar.getMaximum(); } HBar.setValue(-xCoord); repaint(); } /** * Scrolls to an absolute vertical position. * @param position the pixel position to scroll to * @see #scrollHorizontalAbsolute */ public void scrollVerticalAbsolute(int position) { yCoord = -position; if (yCoord > 0) { yCoord = 0; } else if ( (-yCoord) > VBar.getMaximum()) { yCoord = -VBar.getMaximum(); } VBar.setValue(-yCoord); repaint(); } /** * Scrolls to an absolute horizontal position. * @param position the pixel position to scroll to * @see #scrollVerticalAbsolute */ public void scrollHorizontalAbsolute(int position) { xCoord = -position; if (xCoord > 0) { xCoord = 0; } else if ( (-xCoord) > HBar.getMaximum()) { xCoord = -HBar.getMaximum(); } HBar.setValue(-xCoord); repaint(); } /** * Returns the recommended dimensions to properly display this component. * This is a standard Java AWT method which gets called to determine * the recommended size of this component. * * @see #minimumSize */ public Dimension preferredSize() { Dimension s = size(); Dimension m = minimumSize(); return new Dimension(Math.max(s.width, m.width), Math.max(s.height, m.height)); } /** * Returns the minimum dimensions to properly display this component. * This is a standard Java AWT method which gets called to determine * the minimum size of this component. * * @see #preferredSize */ public Dimension minimumSize() { return new Dimension(width, height); } /** * Adds a component to the end of this container. * This is a standard Java AWT method which gets called to add a * component to a container. The specified component is added to * the end of this container. * * @param comp the component to add * @return the added component * @see #remove */ public Component add(Component comp) { setComponent(comp); repaint(); return comp; } /** * Adds a component to the end of this container. * This is a standard Java AWT method which gets called to add a * component to a container. Typically, the specified component is added to * this container at the given zero-relative position index. A * position index of -1 would append the component to the end. * It has been overridden so that the component always gets added to * the end of this container. * * @param comp the component to add * @param pos the zero-relative index at which to add the component or -1 * for end (IGNORED) * @return the added component * @see #remove */ public synchronized Component add(Component comp, int pos) { return add(comp); } /** * Adds a component to the end of this container. * This is a standard Java AWT method which gets called to add a * component to a container. Typically, the specified component is added to * the end of this container, and also added to this container's * layout manager with the given name. * It has been overridden so that the component always gets added to * the end of this container. * * @param name the positioning directive for the layout manager (IGNORED) * @param comp the component to add * @return the added component * @see #remove */ public synchronized Component add(String name, Component comp) { return add(comp); } /** * Removes the specified component from this container. * This is a standard Java AWT method which gets called to remove a * component from a container. When this happens the component's * removeNotify() will also get called to indicate component removal. * * @param comp the component to remove * @see #removeAll * @see #add */ public synchronized void remove(Component comp) { if (comp == VBar || comp == HBar) { return; } super.remove(comp); if (comp == spComponent) { spComponent = null; } } private void addInternalComponents() { super.add(VBar, -1); super.add(HBar, -1); super.add(cornerRect, -1); } /** * Removes all the components from this container. * This is a standard Java AWT method which gets called to remove all * the components from a container. When this happens each component's * removeNotify() will also get called to indicate component removal. * * @see #remove * @see #add */ public synchronized void removeAll() { super.removeAll(); addInternalComponents(); spComponent = null; } /** * Takes no action. * This is a standard Java AWT method which gets called to specify * which layout manager should be used to layout the components in * standard containers. * * Since layout managers CANNOT BE USED with this container the standard * setLayout has been OVERRIDDEN for this container and does nothing. * * @param l the layout manager to use to layout this container's components * (IGNORED) * @see java.awt.Container#getLayout **/ public void setLayout(LayoutManager mgr) { } /** * Moves and/or resizes this component. * This is a standard Java AWT method which gets called to move and/or * resize this component. Components that are in containers with layout * managers should not call this method, but rely on the layout manager * instead. * * @param x horizontal position in the parent's coordinate space * @param y vertical position in the parent's coordinate space * @param width the new width * @param height the new height */ public synchronized void reshape(int x, int y, int width, int height) { repaint(); super.reshape(x, y, width, height); } void placeComponents() { boolean bShowV, bShowH; int barSize = 0; int vWid = 0; int hHt = 0; dimComponent = spComponent.size(); Rectangle rect = bounds(); //???RKM??? Should add an OSPreference for things like this (layout manager would work as well?) if (symantec.itools.lang.OS.isSolaris()) barSize = 17; else if (symantec.itools.lang.OS.isMacintosh()) barSize = 16; else barSize = 15; if (bAllowShowHBar && dimComponent.width > rect.width) { bShowH = true; hHt = barSize; } else { bShowH = false; hHt = 0; } if (bAllowShowVBar && dimComponent.height > (rect.height-hHt)) { bShowV = true; vWid = barSize; if (!bShowH) { if (dimComponent.width > (rect.width-vWid)) { bShowH = true; hHt = barSize; } } } else { bShowV = false; vWid = 0; } hPageSize = rect.width - vWid - vGapWid; vPageSize = rect.height - hHt - hGapHt; if (bShowV) { VBar.reshape(rect.width-barSize, 0, barSize, rect.height-hHt); VBar.setValues(-yCoord, vPageSize, 0, dimComponent.height - vPageSize); VBar.setPageIncrement(vPageSize); if (!bVBarVisible) { bVBarVisible = true; VBar.show(); } } else { if (bVBarVisible) { bVBarVisible = false; VBar.hide(); } yCoord = 0; } if (bShowH) { HBar.reshape(0, rect.height-barSize, rect.width-vWid, barSize); HBar.setValues(-xCoord, hPageSize, 0, dimComponent.width - hPageSize); HBar.setPageIncrement(hPageSize); if (!bHBarVisible) { bHBarVisible = true; HBar.show(); } } else { if (bHBarVisible) { bHBarVisible = false; HBar.hide(); } xCoord = 0; } if (bHBarVisible && bVBarVisible) { int x = rect.width - vWid; int y = rect.height - hHt; int w = rect.width - x + 1; int h = rect.height - y + 1; cornerRect.reshape(x, y, w, h); if (!bCornerRectVisible) { bCornerRectVisible = true; cornerRect.show(); } } else { if (bCornerRectVisible) { bCornerRectVisible = false; cornerRect.hide(); } } spComponent.move(xCoord, yCoord); spComponent.validate(); } }